#include "oled.h"
#include "string.h"

uint8_t oled_GPU_packge[8][128];

#define HI2CX hi2c1

//写命�?
void oled_cmd(uint8_t cmd)
{
	HAL_I2C_Mem_Write(&HI2CX ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&cmd,1,0x100);
}
//写数�?
void oled_data(uint8_t data)
{
	HAL_I2C_Mem_Write(&HI2CX ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&data,1,0x100);
}

void oled_datas(uint8_t * datas,uint16_t length)
{
    HAL_I2C_Mem_Write(&HI2CX ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,datas,length,0x100);
}


void oled_init(void)
{
	HAL_Delay(500);
    oled_cmd(0xAE);//--turn off oled panel
	oled_cmd(0x00);//---set low column address
	oled_cmd(0x10);//---set high column address
	oled_cmd(0x40);//--set start line address  Set Mapping RAM Display Start Line 
	oled_cmd(0x81);//--set contrast control register
	oled_cmd(0x2f);// Set SEG Output Current Brightness
	oled_cmd(0xA1);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
	oled_cmd(0xC8);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
	oled_cmd(0xA6);//--set normal display
	oled_cmd(0xA8);//--set multiplex ratio(1 to 64)
	oled_cmd(0x3f);//--1/64 duty
	oled_cmd(0xD3);//-set display offset	Shift Mapping RAM Counter (0x00~0x3F)
	oled_cmd(0x00);//-not offset
	oled_cmd(0xd5);//--set display clock divide ratio/oscillator frequency
	oled_cmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
	oled_cmd(0xD9);//--set pre-charge period
	oled_cmd(0xF1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
	oled_cmd(0xDA);//--set com pins hardware configuration
	oled_cmd(0x12);
	oled_cmd(0xDB);//--set vcomh
	oled_cmd(0x40);//Set VCOM Deselect Level
	oled_cmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
	oled_cmd(0x02);//
	oled_cmd(0x8D);//--set Charge Pump enable/disable
	oled_cmd(0x14);//--set(0x10) disable
	oled_cmd(0xA4);// Disable Entire Display On (0xa4/0xa5)
	oled_cmd(0xA6);// Disable Inverse Display On (0xa6/a7) 
	oled_cmd(0xAF);
	OLED_Set_Pos(0,0);
	oled_cls();
    oled_on();
		oled_cmd(0x2e);

}


//开启OLED显示    
void oled_on(void)
{
	oled_cmd(0X8D);  //SET DCDC命令
	oled_cmd(0X14);  //DCDC ON
	oled_cmd(0XAF);  //DISPLAY ON
}
 
//关闭OLED显示     
void oled_off(void)
{
	oled_cmd(0X8D);  //SET DCDC命令
	oled_cmd(0X10);  //DCDC OFF
	oled_cmd(0XAE);  //DISPLAY OFF
}		

/*
输入内�?�为oled屏幕的显示坐标，要显示的字�?�、字符大�?
*/
void OLED_Set_Pos(unsigned char x, unsigned char y) 
{ 
	oled_cmd(0xb0+y);
	oled_cmd(((x&0xf0)>>4)|0x10);
	oled_cmd((x&0x0f)|0x01);
} 



//水平滚动
void oled_scroll(void)
{
  oled_cmd(0x2e);//关滚�?
  oled_cmd(0x27);//29向右�?2a向左
  oled_cmd(0x00);//A:空字�?
  oled_cmd(0x02);//B:水平起�?�页
  oled_cmd(0x07);//C:水平滚动速度
  oled_cmd(0x03);//D:水平结束�?
  oled_cmd(0x00);//E:每�?�垂直滚动位�?
  oled_cmd(0xFF);//E:每�?�垂直滚动位�?
  oled_cmd(0x2f);//开滚动
  
}


void pic_inits(my_pics *pics,uint8_t length,uint8_t height,uint8_t pic_datas[])
{
	pics.height = height;
	pics.width = width;
	memcmp(pics->pic,pic_datas,sizeof(pic_datas));
}


void pic_blit(int x,int y,int length,int height,uint8_t* arr)
{
    int i,j;
		uint8_t temp;
    for(i=0;i<8;i++){
        for(j=0;j<128;j++){
            if((j>=x && j<x+length) && (i>=y && i<height/8+y)){
                
                temp=arr[(j-x)+(i-y)*length];
                oled_GPU_packge[i][j]=temp;
            }
            else if((i>0 && i<y) || (i>=y+height/8 && i<8) || (j>0 && j<x) || (j>=x+length && j<128)){
                oled_GPU_packge[i][j]=0x00;
            }          
        }
    }
}


void oled_blit_num(uint8_t x,uint8_t y,float num,uint8_t len)
{
		char chars[128];
		switch(len){
			case 0:
				sprintf(chars,"%d",(int)num);
				break;
			case 1:
				sprintf(chars,"%.1f",num);
				break;
			case 2:
				sprintf(chars,"%.2f",num);
				break;
			case 3:
				sprintf(chars,"%.3f",num);
				break;
			case 4:
				sprintf(chars,"%.4f",num);
				break;
			case 5:
				sprintf(chars,"%.5f",num);
				break;
			case 6:
				sprintf(chars,"%.6f",num);
				break;
			case 7:
				sprintf(chars,"%.7f",num);
				break;
		}
		
		oled_blit_str(x,y,(uint8_t *)chars);
}

void oled_blit_str(uint8_t x,uint8_t y,uint8_t *chr)//128*64
{
	uint8_t st_x=x,st_y=y;
    uint8_t i,j=0,c,k,wei=0;
    uint8_t y_up=st_y/8,y_down=y_up+1;
    uint8_t y_up_d=st_y%8;
    while(chr[j]!='\0'){
        c=chr[j]-32;
        if(x>126){x=0;y++;}
        for(i=0;i<6;i++){
            uint8_t temp=zifu[c][i],t[8];
            for(k=0;k<8;k++){
                t[k]=(temp>>k)&0x01;
            }
            if(y_up_d==0){
                oled_GPU_packge[y_up][st_x+i+wei*6]=temp;
            }
            else{
                uint8_t up_temp=0x00,down_temp=0x00;
                for(k=0;k<8-y_up_d;k++){
                    up_temp|=(t[k]<<(k+y_up_d));
                }
//								for(k=0;k<y_up_d;k++){
//										up_temp=1<<k;
//								}
                for(k=0;k<y_up_d;k++){
                    down_temp|=(t[k+8-y_up_d]<<(k));
                }
                oled_GPU_packge[y_up][st_x+i+wei*6]=up_temp;
                oled_GPU_packge[y_down][st_x+i+wei*6]=down_temp;
            }
        }
        j++;
        wei++;
    }
}

void oled_clear()
{
	int i,j;
	for(i=0;i<8;i++){
		for(j=0;j<128;j++){
			oled_GPU_packge[i][j]=0x00;
		}
	}
}
	

void oled_update()
{
    int i;
    for(i=0;i<8;i++){
        OLED_Set_Pos(0,i);
        oled_datas(oled_GPU_packge[i],128);
    }
}


